home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ABUSESRC.ZIP / AbuseSrc / imlib / input.c < prev    next >
C/C++ Source or Header  |  1996-04-11  |  13KB  |  510 lines

  1. #include "input.hpp"
  2. #include "macs.hpp"
  3.  
  4.  
  5. void button::remap(filter *f)
  6. {
  7.   if (visual)
  8.   {
  9.     f->apply(visual);
  10.     if (pressed)
  11.       f->apply(pressed);
  12.   }
  13. }
  14.  
  15. void button_box::press_button(int id)      // if button box doesn't contain id, nothing happens
  16. {
  17. }
  18.  
  19. void button_box::remap(filter *f)
  20. {
  21.   for (button *b=buttons;b;b=(button *)b->next)
  22.     b->remap(f);
  23. }
  24.  
  25. ifield *button_box::find(int search_id)
  26. {
  27.   if (search_id==id) return this;
  28.   for (ifield *i=(ifield *)buttons;i;i=i->next)
  29.     if (search_id==i->id) return i;
  30.   return NULL;
  31. }
  32.  
  33. button_box::button_box(int X, int Y, int ID, int MaxDown, button *Buttons, ifield *Next)
  34. {
  35.   x=X; y=Y; id=ID; next=Next; 
  36.   buttons=Buttons;
  37.   maxdown=MaxDown;
  38.   if (buttons && maxdown) buttons->push();  // the first button is automatically selected!
  39. }
  40.  
  41. button_box::~button_box()
  42. {
  43.   while (buttons)
  44.   {
  45.     button *b=buttons;
  46.     buttons=(button *)buttons->next;
  47.     delete b;
  48.   }
  49. }
  50.  
  51. void button_box::area(int &x1, int &y1, int &x2, int &y2, window_manager *wm)
  52. {
  53.   button *b=buttons;
  54.   if (!b) return ;
  55.   else
  56.   {
  57.     b->area(x1,y1,x2,y2,wm);
  58.     int xp1,yp1,xp2,yp2;
  59.     for (b=(button *)b->next;b;b=(button *)b->next)
  60.     {
  61.       b->area(xp1,yp1,xp2,yp2,wm);
  62.       if (xp1<x1) x1=xp1;
  63.       if (xp2>x2) x2=xp2;
  64.       if (yp1<y1) y1=yp1;
  65.       if (yp2>y2) y2=yp2;
  66.     }          
  67.   }
  68. }
  69.  
  70. void button_box::draw_first(image *screen, window_manager *wm)
  71. {
  72.   for (button *b=buttons;b;b=(button *)b->next)
  73.     b->draw_first(screen,wm);
  74. }
  75.  
  76. void button_box::draw(int active, image *screen, window_manager *wm)
  77. {
  78.   return ;
  79. }
  80.  
  81. char *button_box::read()
  82. {
  83.   for (button *b=buttons;b;b=(button *)b->next)
  84.   {
  85.     if (*((int *)b->read())==0)
  86.       return (char *)b;
  87.   }
  88.   return NULL;
  89. }
  90.  
  91. void button_box::handle_event(event &ev, image *screen, window_manager *wm, input_manager *im)
  92. {
  93.   switch (ev.type)
  94.   {
  95.     case EV_MOUSE_BUTTON :
  96.     {
  97.       int x1,y1,x2,y2;
  98.       int found=0;
  99.       for (button *b=buttons;!found && b;b=(button *)b->next)  // see if the user clicked on a button
  100.       {
  101.     b->area(x1,y1,x2,y2,wm);
  102.     if (ev.mouse_move.x>=x1 && ev.mouse_move.x<=x2 && 
  103.         ev.mouse_move.y>=y1 && ev.mouse_move.y<=y2)
  104.     {
  105.       b->handle_event(ev,screen,wm,im);
  106.  
  107.       int total=0;
  108.       button *b2=buttons;
  109.       for (;b2;b2=(button *)b2->next)
  110.         if (*((int *)b2->read())==0)
  111.           total++;
  112.  
  113.       int draw=1;
  114.       if (*((int *)b->read())==0)  // did the user press or release the button
  115.       {
  116.         if (total>maxdown)
  117.         {
  118.           for (b2=buttons;total>maxdown && b2;b2=(button *)b2->next)
  119.             if ((b!=b2 || maxdown==0) && *((int *)b2->read())==0)
  120.         {
  121.           total--;
  122.           b2->push();
  123.           b2->draw_first(screen,wm);
  124.         }
  125.         }
  126.         b->draw_first(screen,wm);
  127.       } else if (total==0 && maxdown)
  128.         b->push();    // don't let the user de-press a button if non others are selected.     
  129.  
  130.       found=1; // don't look at anymore buttons
  131.  
  132.     }
  133.       }
  134.     } break;   
  135.   }
  136. }
  137.  
  138.  
  139. void button_box::add_button(button *b)
  140. {
  141.   b->next=buttons;
  142.   buttons=b;
  143. }
  144.  
  145.  
  146. void button_box::arrange_left_right(window_manager *wm)
  147. {
  148.   button *b=buttons;
  149.   int x_on=x,x1,y1,x2,y2;
  150.   for (;b;b=(button *)b->next)
  151.   {
  152.     b->area(x1,y1,x2,y2,wm);
  153.     b->x=x_on;
  154.     b->y=y;
  155.     x_on+=(x2-x1+1)+1;
  156.   }  
  157. }
  158.  
  159. void button_box::arrange_up_down(window_manager *wm)
  160. {  
  161.   button *b=buttons;
  162.   int y_on=y,x1,y1,x2,y2;
  163.   for (;b;b=(button *)b->next)
  164.   {
  165.     b->area(x1,y1,x2,y2,wm);
  166.     b->y=y_on;
  167.     b->x=x;
  168.     y_on+=(y2-y1+1)+1;
  169.   }  
  170. }
  171.  
  172. void button::change_visual(image *new_visual)
  173. {
  174.   CHECK(visual);
  175.   visual=new_visual;
  176. }
  177.  
  178. void button::area(int &x1, int &y1, int &x2, int &y2, window_manager *wm)
  179. {  
  180.   x1=x; y1=y; 
  181.   if (pressed)
  182.   {
  183.     x2=x+pressed->width()-1;
  184.     y2=y+pressed->height()-1;
  185.   }
  186.   else
  187.   {
  188.     if (text)
  189.     {    
  190.       x2=x+wm->font()->width()*strlen(text)+6; 
  191.       y2=y+wm->font()->height()+6; 
  192.     } else
  193.     {
  194.       x2=x+6+visual->width();
  195.       y2=y+6+visual->height();
  196.     }
  197.   }
  198. }
  199.  
  200.  
  201. button::button(int X, int Y, int ID, char *Text, ifield *Next)
  202. {  
  203.   x=X; y=Y; id=ID; 
  204.   act_id=-1;
  205.   text=strcpy((char *)jmalloc(strlen(Text)+1,"input button"),Text); 
  206.   up=1; next=Next; act=0;
  207.   visual=NULL;
  208.   pressed=NULL;
  209. }
  210.  
  211.  
  212. button::button(int X, int Y, int ID, image *vis, ifield *Next)
  213. { x=X; y=Y; id=ID; text=NULL; 
  214.   act_id=-1;
  215.   visual=vis; up=1; next=Next; act=0; 
  216.   pressed=NULL;
  217. }
  218.  
  219. button::button(int X, int Y, int ID, image *Depressed, image *Pressed, image *active, ifield *Next)
  220. { x=X; y=Y; id=ID; text=NULL; 
  221.   act_id=-1;
  222.   visual=Depressed; up=1; next=Next; act=0; 
  223.   pressed=Pressed;
  224.   act_pict=active;
  225. }
  226.  
  227.  
  228. void text_field::change_data(char *new_data, int new_cursor, // cursor==-1, does not change it.
  229.                  int active, image *screen, window_manager *wm)
  230. {
  231.   if (strlen(format)<strlen(new_data))
  232.     data=(char *)jrealloc(data,strlen(new_data),"text field input");
  233.  
  234.   strcpy(data,new_data);
  235.   if (new_cursor!=-1)
  236.     cur=new_cursor;
  237.   draw_first(screen,wm);
  238.   draw(active,screen,wm);
  239. }
  240.  
  241. char *text_field::read()
  242. {
  243.   while (*data && data[strlen(data)-1]==' ') data[strlen(data)-1]=0;
  244.   return data;
  245. }
  246.  
  247. #ifdef __POWERPC__
  248. #pragma global_optimizer on
  249. #endif
  250.  
  251. void text_field::handle_event(event &ev, image *screen, window_manager *wm, input_manager *im)
  252. {
  253.   int xx;
  254.   if (ev.type==EV_KEY)
  255.   {
  256.     switch (ev.key)
  257.     {
  258.       case JK_LEFT : if (cur) { draw_cur(wm->dark_color(),screen,wm); cur--;
  259.                            draw_cur(wm->bright_color(),screen,wm); } break; 
  260.       case JK_RIGHT : if (cur<strlen(format)-1) { draw_cur(wm->dark_color(),screen,wm); cur++;
  261.                            draw_cur(wm->bright_color(),screen,wm); } break; 
  262.       case JK_END : if (cur!=last_spot()) 
  263.                           { draw_cur(wm->dark_color(),screen,wm); cur=last_spot(); 
  264.                             if (cur==strlen(format)-1) cur--; 
  265.                            draw_cur(wm->bright_color(),screen,wm); } break; 
  266.       case JK_HOME : if (cur) 
  267.                           { draw_cur(wm->dark_color(),screen,wm); cur=0;
  268.                            draw_cur(wm->bright_color(),screen,wm); } break; 
  269.       case JK_BACKSPACE : if (cur)
  270.          { draw_cur(wm->dark_color(),screen,wm); cur--;
  271.            for (xx=cur;xx<strlen(format)-1;xx++)
  272.              data[xx]=data[xx+1];
  273.            data[strlen(format)-1]=' ';
  274.            draw_text(screen,wm);
  275.            draw_cur(wm->bright_color(),screen,wm); 
  276.            wm->push_event(new event(id,(char *)this));
  277.          } break; 
  278.       default : if (ev.key>=' ' && ev.key<='~')
  279.          { 
  280.            draw_cur(wm->dark_color(),screen,wm); 
  281.            for (xx=strlen(format)-1;xx>cur && xx>0;xx--)
  282.              data[xx]=data[xx-1];
  283.            data[cur]=ev.key;
  284.            if (cur<strlen(format)-1)
  285.              cur++;
  286.        data[strlen(format)]=0;
  287.            draw_text(screen,wm);
  288.            draw_cur(wm->bright_color(),screen,wm); 
  289.            wm->push_event(new event(id,(char *)this));
  290.          } break;
  291.     }
  292.   } 
  293. }
  294.  
  295. #ifdef __POWERPC__
  296. #pragma global_optimizer reset
  297. #endif
  298.  
  299. void text_field::draw(int active, image *screen, window_manager *wm)
  300. {
  301.   if (active)
  302.   {
  303.     screen->rectangle(xstart(wm),y,xend(wm),yend(wm),wm->bright_color());
  304.     draw_cur(wm->bright_color(),screen,wm);
  305.   }
  306.   else
  307.   {
  308.     screen->rectangle(xstart(wm),y,xend(wm),yend(wm),wm->dark_color());
  309.     draw_cur(wm->dark_color(),screen,wm);
  310.   }
  311. }
  312.  
  313. void text_field::area(int &x1, int &y1, int &x2, int &y2, window_manager *wm)
  314. {
  315.   x1=x; y1=y; 
  316.   x2=xend(wm);
  317.   y2=yend(wm);
  318. }
  319.  
  320. text_field::text_field(int X, int Y, int ID, char *Prompt, char *Format, 
  321.                                                      char *Data, ifield *Next)
  322. {
  323.   int slen=(strlen(Format)>strlen(Data) ? strlen(Format) : strlen(Data));
  324.  
  325.   x=X; y=Y; id=ID;
  326.   prompt=strcpy((char *)jmalloc(strlen(Prompt)+1,"text_field::prompt"),Prompt);
  327.   format=strcpy((char *)jmalloc(slen+1,"text_field::format"),Format);
  328.   data=strcpy((char *)jmalloc(slen+1,"text_field::data"),Data);
  329.   cur=strlen(data);
  330.   while (cur && data[cur-1]==' ') cur--;
  331.   next=Next;
  332. }
  333.  
  334. text_field::text_field(int X, int Y, int ID, char *Prompt, char *Format, 
  335.                                double Data, ifield *Next)
  336. {
  337.   char num[20];
  338.   sprintf(num,"%lg",Data);  
  339.   int slen=(strlen(Format)>strlen(num) ? strlen(Format) : strlen(num));
  340.   x=X; y=Y; id=ID;
  341.   prompt=strcpy((char *)jmalloc(strlen(Prompt)+1,"text_field::prompt"),Prompt);
  342.   format=strcpy((char *)jmalloc(slen+1,"text_field::format"),Format);
  343.   data=strcpy((char *)jmalloc(slen+1,"text_field::data"),num);
  344.   cur=strlen(num);
  345.   while (cur && data[cur-1]==' ') cur--;
  346.   next=Next;
  347. }
  348.  
  349.  
  350. void button::push()
  351. { up=!up; }
  352.  
  353. void button::handle_event(event &ev, image *screen, window_manager *wm, input_manager *im)
  354. {
  355.   if ((ev.type==EV_KEY && ev.key==13) || (ev.type==EV_MOUSE_BUTTON &&
  356.                                          ev.mouse_button))
  357.   {
  358.     int  x1,y1,x2,y2;
  359.     area(x1,y1,x2,y2,wm);
  360.     up=!up;
  361.     draw_first(screen,wm);
  362.     draw(act,screen,wm);
  363.     wm->push_event(new event(id,(char *)this));
  364.   }
  365. }
  366.  
  367. void button::draw(int active, image *screen, window_manager *wm)
  368. {
  369.   int x1,y1,x2,y2,color=(active ? wm->bright_color() : wm->medium_color());  
  370.   area(x1,y1,x2,y2,wm); 
  371.   if (active!=act  && act_id!=-1 && active)
  372.     wm->push_event(new event(act_id,NULL));
  373.     
  374.   if (pressed)
  375.   {
  376.     if (up)
  377.     {
  378.       if (!active)
  379.         visual->put_image(screen,x,y);
  380.       else
  381.         pressed->put_image(screen,x,y);
  382.     } else act_pict->put_image(screen,x,y);
  383.   }
  384.   else
  385.   {
  386.     screen->rectangle(x1+2,y1+2,x2-2,y2-2,color);
  387.     act=active;
  388.   }
  389. }
  390.  
  391. void button::draw_first(image *screen, window_manager *wm)
  392. {
  393.   if (pressed)  
  394.     draw(0,screen,wm);
  395.   else
  396.   {
  397.  
  398.     int x1,y1,x2,y2;
  399.     area(x1,y1,x2,y2,wm);
  400.     
  401.  
  402.     if (up)
  403.     {
  404.       screen->rectangle(x1,y1,x2,y2,wm->black());
  405. //      screen->wiget_bar(,wm->bright_color(),wm->medium_color(),wm->dark_color()); 
  406.       screen->wiget_bar(x1+1,y1+1,x2-1,y2-1,wm->bright_color(),wm->medium_color(),wm->dark_color()); 
  407.       if (text)
  408.       {
  409.         wm->font()->put_string(screen,x+4,y+5,text,wm->black());
  410.         wm->font()->put_string(screen,x+3,y+4,text);
  411.       }
  412.       else visual->put_image(screen,x+3,y+3,1);
  413.     } else
  414.     {
  415.       screen->line(x1,y1,x2,y1,wm->dark_color());
  416.       screen->line(x1,y1,x1,y2,wm->dark_color());
  417.       screen->line(x2,y1+1,x2,y2,wm->bright_color());
  418.       screen->line(x1+1,y2,x2,y2,wm->bright_color());
  419.       screen->bar(x1+1,y1+1,x2-1,y2-1,wm->medium_color());
  420.       if (visual)
  421.         visual->put_image(screen,x1+3,y1+3,1);
  422.       else
  423.       {
  424.         wm->font()->put_string(screen,x+4,y+5,text,wm->black());
  425.         wm->font()->put_string(screen,x+3,y+4,text);
  426.       }
  427.     }  
  428.   }
  429. }
  430.  
  431. void text_field::draw_first(image *screen, window_manager *wm)
  432. {
  433.   wm->font()->put_string(screen,x,y+3,prompt);
  434.   screen->bar(xstart(wm),y,xend(wm),yend(wm),wm->dark_color());
  435.   wm->font()->put_string(screen,xstart(wm)+1,y+3,data);
  436. }
  437.  
  438.  
  439. void text_field::draw_cur(int color, image *screen, window_manager *wm)
  440. {
  441.   screen->bar(xstart(wm)+cur*wm->font()->width()+1,
  442.                       yend(wm)-2,
  443.                       xstart(wm)+(cur+1)*wm->font()->width(),
  444.                       yend(wm)-1,color);
  445. }
  446.  
  447.  
  448.  
  449. info_field::info_field(int X, int Y, int ID, char *info, ifield *Next)
  450. {
  451.   x=X; y=Y; id=ID; next=Next;
  452.   text=strcpy((char *)jmalloc(strlen(info)+1,"info_field"),info);
  453.   w=-1;
  454. }
  455.  
  456.  
  457. void info_field::area(int &x1, int &y1, int &x2, int &y2, window_manager *wm)
  458. {
  459.   if (w==-1)     // if we haven't calculated this yet
  460.   {
  461.     int fw=wm->font()->width(),fh=wm->font()->height(),maxw=0;
  462.     char *info=text;
  463.     for (w=fw,h=fh+1;*info;info++)
  464.     {
  465.       if (w>maxw) maxw=w;
  466.       if (*info=='\n')
  467.       {
  468.     h+=fh+1;
  469.     w=1;
  470.       }
  471.       else w+=fw;      
  472.     }
  473.     w=maxw;
  474.   }      
  475.   x1=x;
  476.   y1=y;
  477.   x2=x+w;
  478.   y2=y+h;
  479. }
  480.  
  481. void info_field::put_para(image *screen, char *st, int dx, int dy, 
  482.               int xspace, int yspace, JCFont *font, int color)
  483. {
  484.   int ox=dx;
  485.   while (*st)
  486.   {
  487.     if (*st=='\n')
  488.     {
  489.       dx=ox;
  490.       dy+=yspace;
  491.     }
  492.     else
  493.     {
  494.       font->put_char(screen,dx,dy,*st,color);
  495.       dx+=xspace;
  496.     }
  497.     st++;
  498.   }
  499. }
  500.  
  501. void info_field::draw_first(image *screen, window_manager *wm)
  502. {
  503.   put_para(screen,text,x+1,y+1,wm->font()->width(),wm->font()->height(),wm->font(),wm->black());
  504.   put_para(screen,text,x,y,wm->font()->width(),wm->font()->height(),wm->font(),wm->bright_color());
  505. }
  506.  
  507.  
  508.  
  509.  
  510.